import type { Response } from '@/api/config/types';
import type { DataNode } from 'ant-design-vue/es/tree';
import axios, { type AxiosResponse } from 'axios';

import { requestFile } from '@/api/config/utils';
import { fileUploader } from '@/api/utils/file';
import {
  uploadCancelToken,
  uploadStatus,
} from '@/views/modules/system/folder/content/subnodes/data/config';
import type { UploadFile } from '@/views/modules/system/folder/data/types';
import { message } from 'ant-design-vue';
import type { FileAttr } from './types';
import createRequestInstance from '@/api/config/request';

/**
 * @param path 需要查询的路径，如果为空，则查询系统根目录
 * @param onlyFolder 仅查询文件夹
 *  */
export const getSystemPath = (path: string = '', onlyFolder: boolean = false) => {
  return axios.get<Response<DataNode[]>>(`tool/file/path`, {
    params: {
      path,
      onlyFolder,
    },
  });
};
/**
 * @description 根据路径浏览文件
 * @param path 需要查询的路径，不能为空，且一定是文件
 *  */
export const viewFile = async (path: string) => {
  return requestFile({
    url: 'tool/file/viewFile',
    method: 'get',
    params: {
      path,
    },
  });
};

type FolderType = 'folder' | 'file';

/**
 * @params {path} 文件完整路径
 * @params {type} 文件类型
 * @description 创建文件或文件夹，文件夹也是特殊的文件
 */
export const createFile = (path: string, type: FolderType) => {
  return axios.get<Response<DataNode[]>>(`tool/file/createFile`, {
    params: {
      path,
      type,
    },
  });
};

/**
 * @description: 根据路径删除一个文件夹
 * @param {string} path
 */
export const deleteFiles = (path: string[]) => {
  return axios.delete<Response>(`tool/file/deleteFile`, {
    data: `${path.join(',')}`,
  });
};

export const renameFile = (oldFileName: string, newFileName: string) => {
  return axios.put<Response>(`tool/file/renameFile`, {
    oldFileName,
    newFileName,
  });
};

/**
 * @description:
 * @param {string} targetPath 目标路径
 * @param {string} files 复制的文件
 */
export const clonedFiles = (targetPath: string, files: string[]) => {
  return axios.post<Response>(`tool/file/cloneFile`, {
    targetPath,
    files: files.join(','),
  });
};

export const fileAttr = (path: string) => {
  return axios.get<Response<FileAttr>>(`tool/file/fileAttr`, {
    params: {
      path,
    },
  });
};

export const fileSave = (path: string, content: string) => {
  return axios.post(`tool/file/saveFile`, {
    path,
    content,
  });
};

export const downloadFile = (path: string) => {
  return requestFile({
    url: 'tool/file/download',
    method: 'get',
    params: {
      path,
    },
  });
};

/**
 * @description: 上传文件到服务端
 * @param {string} root 项目根路径，可选不填则使用后端默认
 * @param {UploadFile} files
 */
// files: UploadFile[], root: string = ''

type UploadFileProps = {
  files: UploadFile[];
  root?: string;
  /**
   *  common/custom/upload:自定义上传
   *  common/upload:上传到静态资源目录
   *  oss/uploads:上传多个文件
   * */
  url?: 'common/custom/upload' | 'common/upload' | 'common/uploads';
};
export const uploadFiles = async (config: UploadFileProps): Promise<string[]> => {
  // 通过 axios 发送 POST 请求
  uploadCancelToken.value = axios.CancelToken.source();
  try {
    uploadStatus.value = 'loading';
    const { response, cancelToken } = await fileUploader({
      files: config.files,
      url: `${config.url || 'common/custom/upload'}`,
      params: {
        path: config.root,
      },
    });
    uploadCancelToken.value = cancelToken;
    if (response.code === '401') {
      message.warn(response.msg);
    } else if (response.code === 200) {
      message.success('文件已上传');
    }
    uploadStatus.value = 'end';

    return response.data;
  } catch (error: any) {
    message.warn('出了点问题', error.toString());
    return [];
  }
};

interface UploadProfileResp {
  msg: string;
  urls: string;
  code: number;
  newFileNames: string;
  fileNames: string;
  originalFilenames: string;
}
/* 上传到静态目录 */
export const uploadToProfile = async (
  config: UploadFileProps,
): Promise<AxiosResponse<UploadProfileResp>> => {
  const http = createRequestInstance();
  const formData = new FormData();
  Array.from(config.files).forEach(file => {
    formData.append('files', file.file, file.path || file.file.name);
  });
  const response = await http.post(config.url || 'common/uploads', formData);
  return response;
};
